package rensoft.portfolio.client.view.viewer;

import static com.google.gwt.query.client.GQuery.$;
import static com.google.gwt.query.client.GQuery.$$;
import rensoft.gwt.client.event.EventFunction;
import rensoft.gwt.client.view.View;
import rensoft.portfolio.client.model.titles.Page;
import rensoft.portfolio.client.model.titles.Title;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.query.client.Properties;
import com.google.gwt.query.client.css.CSS;
import com.google.gwt.query.client.css.Length;
import com.google.gwt.query.client.plugins.effects.PropertiesAnimation.Easing;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;

import static cs.java.lang.Lang.doLater;

import cs.java.lang.Run;



public class PageViewer extends View<Widget> {

	static Binder uiBinder = GWT.create(Binder.class);

	private static final int LENGTH = 940;

	@UiField SimplePanel currentPanel;
	@UiField SimplePanel loadingPanel;
	private int openIndex = -1;
	private TitlePageWidgetProvider pageProvider;

	public PageViewer() {
		initWidget(uiBinder.createAndBindUi(this));
	}

	public void close() {
		currentPanel.setWidget(null);
		openIndex = -1;
		unregister(Title.ON_PAGE_CHANGE);
	}

	public void show(TitlePageWidgetProvider pageProvider) {
		this.pageProvider = pageProvider;
		openIndex = -1;
		showCurrentPage();
		registerReplace(getTitle(), Title.ON_PAGE_CHANGE, new EventFunction<Page>() {
			public void run(Page value) {
				showCurrentPage();
			}
		});
	}

	private void animate(SimplePanel panel) {
		$(panel).css(CSS.POSITION.with(Position.ABSOLUTE)).animate(getPanelAnimationProperties(),
		    QUICK_ANIMATION, Easing.SWING);
	}

	private Properties getPanelAnimationProperties() {
		if (isNextAnimation()) return $$("left:'-=" + LENGTH + "',right:'+=" + LENGTH + "'");
		return $$("left:'+=" + LENGTH + "',right:'-=" + LENGTH + "'");
	}

	private Title getTitle() {
		return pageProvider.getTitle();
	}

	private boolean isNextAnimation() {
		return getTitle().getCurrentIndex() >= openIndex;
	}

	private void setBeforeAnimationLoadingPanelPosition() {
		if (isNextAnimation()) {
			$(loadingPanel).css(CSS.LEFT.with(Length.px(LENGTH)));
			$(loadingPanel).css(CSS.RIGHT.with(Length.px(-LENGTH)));
		} else {
			$(loadingPanel).css(CSS.LEFT.with(Length.px(-LENGTH)));
			$(loadingPanel).css(CSS.RIGHT.with(Length.px(LENGTH)));
		}
	}

	private void showCurrentPage() {
		doLater(new Run() {
			public void run() {
				animate(currentPanel);
				loadingPanel.setWidget(pageProvider.createPageWidget());
				setBeforeAnimationLoadingPanelPosition();
				animate(loadingPanel);
				switchPanels();
				openIndex = getTitle().getCurrentIndex();
			}
		});
	}

	private void switchPanels() {
		SimplePanel tmpCurrentPanel = currentPanel;
		currentPanel = loadingPanel;
		loadingPanel = tmpCurrentPanel;
	}

	interface Binder extends UiBinder<Widget, PageViewer> {}
}
